/**
 * 单页webapp MainWin对象
 */
/*global $win $config define window Base64 Test document Waiting History navigator iScroll :true*/
define([
    "jquery",
    "config",
    "topbar",
    "footer",
    "iscroll-probe",
    "history",
    "ajax"
], function($, Config, Topbar, Footer, IScroll) {
    function MainWin(width, height) {
        this.width = width;
        this.height = height;
        window.$config = new Config();
        window.Topbar = Topbar;
        window.Footer = Footer;
        this.topbar = new Topbar("header");
        this.topbar.initCommon();
        this.footer = new Footer("footer");
        this.footer.hide();

        this.container = null;
        this.errorDiv = null;
        // 页面跳转时的参数
        this.requestParams = null;

        // 页面动作
        // show: 显示页面
        // backward: 后退
        // forward: 前进
        this._pageAction = null;
        // session
        this._session = {};
        // jscallback
        this._jsCbMap = {};
        // downloader
        this._downloadQueue = {};

        // 初始化
        this._init();

        /** 当前页面对象
         * initDom
         *  必填，初始化UI
         * initData
         *  必填，初始化数据，返回jqxhr对象，如果未返回则直接调用initEvent
         * initEvent
         *  必填，绑定页面事件，initData调用或者initData异步请求成功后200ms调用
         * beforeBackward
         *  选填，点击返回或者后退键之后、页面返回上一级之前调用
         *  如果返回true，表明此次后退事件已经被消费
         *  如果返回false或者不返回，则200ms之后判断是否可以后退，如果不可以则退出webView
         * beforeShowContent
         *  选填，展示页面内容前调用
         *      根据initData返回结果的情况，展示页面或者展示错误页面
         *      注意，如果实现该方法，必须在实现中手动调用$win.showContent()方法，否则不会展示页面内容
         *  如果不填，则直接展示页面
         */
        this._currentPage = {};

        // 用户信息
        this.userInfo = {};
        this.autoplay = "1"; //"1"播放"0"静音
        this.scheme = "longtu";
        this._initSystem();
    }

    // -----------------------------------------------------------------------------------------------------------------------------------------------
    // 页面流转控制模块begin
    // -----------------------------------------------------------------------------------------------------------------------------------------------
    /**
     * MainWin初始化方法
     */
    MainWin.prototype._init = function() {
        // 处理statechange事件
        var me = this;
        me.container = $("[maincontainer=true]");
        me.container.addClass("mainContainer");
        me._initContainerSize();
        me.errorDiv = $("#mainErrorDiv");
        me.errorDiv.css("line-height", (this.height / 2) + "px");
        me.jsRegister("backward", me.backward);
        me.jsRegister("cancel", me.cancel);
        History.Adapter.bind(window, "statechange", function() {
            var state = History.getState();
            if (state.data.page) {
                me._showPage(state.data);
            }
        });
    };

    /**
     * 初始化container大小
     * container.height=mainwin.height-topbar.height-footer.height
     * container.width=mainwin.width
     * @return null
     */
    MainWin.prototype._initContainerSize = function() {
        this.container.width(this.width);
        this.container.height(this.height - this.topbar.getHeight() - this.footer.getHeight());
    };

    /**
     * 返回初始化时窗口大小
     */
    MainWin.prototype.getScreenSize = function() {
        return [this.width, this.height];
    };

    /**
     * 展示config中配置的首页
     */
    MainWin.prototype.loadHomepage = function() {
        if (!$.isNotBlank($config.homepage)) {
            $.MessageAlert({content: "未设定首页，请检查config.js"});
            return;
        }
        this.showPage($config.homepage.url, {
            moduleName: $config.homepage.moduleName
        }, false);
    };

    // 后退
    MainWin.prototype.backward = function() {
        this._pageAction = "backward";

        var invokeBack = this._currentPage.beforeBackward;
        if (invokeBack && typeof invokeBack == "function") {
            var consume = invokeBack.call(this._currentPage);
            if (consume) {
                return;
            }
        }
        // 使用异步实现，新版本中webview方法必须运行在ui线程中
        this.jsRegister("backward_cb", function(result) {
            if (JSON.parse(result)) {
                History.back();
            } else {
                $win.cancel();
            }
        });
        window.location.href = this.scheme + "://gobackward";
    };

    // 前进
    MainWin.prototype.forward = function() {
        this._pageAction = "forward";
        History.forward();
    };

    /**
     * 展示页面
     * url:
     *      页面相对路径
     * params:
     *      网页加载参数，包括如下内置参数（关键字保留，不要占用）
     *          showTopbar: 是否显示topbar，默认是true
     *          moduleName: main.js中通过requireJS引入的module名，用于加载目标页面脚本
     *
     *          内部参数不要占用
     *          title: 页面标题，默认document.title
     *          page: 默认参数，页面相对路径
     *          sdata: 默认参数，时间戳，用于防止浏览器缓存
     *
     * cangoback:
     *      展示页面后是否允许后退到之前的页面
     *
     */
    MainWin.prototype.showPage = function(url, params, cangoback) {
        var page = url;
        params = $.extend({
            showTopbar: true
        }, params);
        url = $config.getUrl(url, params);
        params.page = page;
        params.sdata = new Date().getTime();
        var title = params.title
            ? params.title
            : document.title;
        this._pageAction = "show";

        if (cangoback == false) {
            History.replaceState(params, title, url);
        } else {
            History.pushState(params, title, url);
        }
    };

    /**
     * 内部函数，用于页面初始化前的窗口内容重置
     */
    MainWin.prototype._reset = function() {
        // 中断所有http请求
        $.abort();
        // 重置UI
        this.topbar.initCommon();
        this.footer.reset();
        $(".dw-modal").remove();
        $("#messagebox").remove();
        this.container.show();
        this.errorDiv.hide();
        // 重置当前页面
        this._currentPage = {};
    };

    /**
     * 内部函数，展示页面
     */
    MainWin.prototype._showPage = function(data) {
        // 重置
        this._reset();
        // 设置参数
        this._saveParams(data);
        // 处理topbar和整体框架
        if (data.showTopbar) {
            $win.getTopbar().show();
            this.container.addClass("mainContainer");
        } else {
            $win.getTopbar().hide();
            this.container.removeClass("mainContainer");
        }
        this._initContainerSize();
        var _this = this;
        // 页面加载完成之前隐藏页面布局
        if (Waiting && Waiting.show) {
            Waiting.show();
        }
        this.hideContent();
        this.container.load($config.getLocation(data.page), function() {
            if ($.isNotBlank(data.moduleName)) {
                require([data.moduleName], function(PageModule) {
                    $win._currentPage = new PageModule(data);
                    if (_this._checkPageEvent()) {
                        var context = _this.getPageContext();
                        _this._currentPage.initDom.call(context);
                        var xhrArray = _this._currentPage.initData.call(context);
                        try {
                            if (xhrArray && $.isArray(xhrArray)) {
                                $.when.apply($, xhrArray).then(function() {
                                    // 成功
                                    setTimeout(function() {
                                        if (_this._currentPage.beforeShowContent && typeof _this._currentPage.beforeShowContent == "function") {
                                            _this._currentPage.beforeShowContent.call(context);
                                        } else {
                                            _this.showContent();
                                        }
                                        _this._currentPage.initEvent.call(context);
                                    }, 500);
                                }, function(e) {
                                    // 失败
                                    $win.log("initData执行失败，" + e.stack);
                                    _this.showErrorPage();
                                });
                            } else {
                                setTimeout(function() {
                                    if (_this._currentPage.beforeShowContent && typeof _this._currentPage.beforeShowContent == "function") {
                                        _this._currentPage.beforeShowContent.call(context);
                                    } else {
                                        _this.showContent();
                                    }
                                    _this._currentPage.initEvent.call(context);
                                }, 500);
                            }
                        } catch (e) {
                            $win.log("initData后续错误：" + e.stack);
                            _this.showErrorPage();
                        }
                    } else {
                        $win.log("页面未注册initDom,initData,initEvent函数");
                        _this.backward();
                    }
                });
            }
        });
    };

    /**
     * 展示默认错误页面
     */
    MainWin.prototype.showErrorPage = function() {
        this.container.hide();
        this.errorDiv.show();
        this.errorDiv.click(function() {
            $win.refresh();
        });
    };

    /**
     * 隐藏页面内容
     */
    MainWin.prototype.hideContent = function() {
        this.container.addClass("ml100");
    };

    /**
     * 展示页面内容
     */
    MainWin.prototype.showContent = function() {
        if (Waiting && Waiting.show) {
            Waiting.hide();
        }
        this.container.removeClass("ml100");
        this.errorDiv.hide();
    };

    /**
     * 刷新当前页面
     */
    MainWin.prototype.refresh = function() {
        var url = this.requestParams.page;
        var params = $.extend({}, this.requestParams);
        delete params.page;
        this.showPage(url, params, false);
    };

    /**
     * 获取当前的页面对象
     */
    MainWin.prototype.getPageContext = function() {
        return this._currentPage;
    };

    /**
     * 获取参数
     */
    MainWin.prototype.getParams = function() {
        return this.requestParams;
    };

    /**
     * 内部方法，保存页面参数
     */
    MainWin.prototype._saveParams = function(data) {
        this.requestParams = data;
    };

    /**
     * 内部函数，用于检测页面对象是否实现了必须的方法
     */
    MainWin.prototype._checkPageEvent = function() {
        return $.isFunc(this._currentPage.initDom) && $.isFunc(this._currentPage.initData) && $.isFunc(this._currentPage.initEvent);
    };

    /**
     * 打开新的webview窗口
     * page:
     *      新页面地址
     * params:
     *      新页面参数
     *          showTopbar: 是否显示topbar，默认是true
     *          moduleName: main.js中通过requireJS引入的module名，用于加载目标页面脚本
     *
     *          内置参数
     *          project: 目标页面所在项目，默认当前项目由$config.project配置
     *          pageType: 页面类型, 0表示内置页面，1表示外链，默认0
     *          showNativeTopbar: 是否展示webview的系统默认topbar，默认false
     *          nativeTitle: webview的系统默认topbar的title
     *
     * callback:
     *      新页面关闭时执行的回调，接受JSON对象作为参数，参见cancel方法
     *
     * 注意
     *      每个窗口中的全局变量是不通用的，对于全局变量的修改不会刷新到其他win，需要手动刷新
     *      比如在newWin中修改了登录用户信息，返回原始窗口的时候需要重新更新登录用户信息
     *
     */
    MainWin.prototype.showNewWin = function(page, params, callback) {
        params = $.extend({
            showTopbar: true
        }, params);

        var pageTypeStr = (params.pageType == 1)
            ? "TYPE_OUTLINK"
            : "TYPE_INNERLINK";
        var nativeTopbar = params.showNativeTopbar || false;
        var nativeTitle = params.nativeTitle || "";
        var project = params.project || $config.project;
        delete params.nativeTitle;
        delete params.showNativeTopbar;
        delete params.pageType;
        delete params.project;

        var urlParam = {
            "project": project,
            "page": page,
            "params": JSON.stringify(params),
            "type_tag": pageTypeStr,
            "native_topbar": nativeTopbar,
            "title": nativeTitle
        };
        this.jsRegister("newwin", callback);
        window.location.href = this.scheme + "://newwin?" + Base64.encode(JSON.stringify(urlParam));
    };

    /**
     * 退出webview
     */
    MainWin.prototype.cancel = function(data) {
        data = data || {};
        window.location.href = this.scheme + "://cancelwebview?" + Base64.encode(JSON.stringify(data));
    };

    /**
     * 退出所有打开的webview，只剩余堆栈底部的
     */
    MainWin.prototype.cancelAll = function(data) {
        data = data || {};
        window.location.href = this.scheme + "://cancelallwebview?" + Base64.encode(JSON.stringify(data));
    };
    // -----------------------------------------------------------------------------------------------------------------------------------------------
    // 页面流转控制模块end
    // -----------------------------------------------------------------------------------------------------------------------------------------------

    // -----------------------------------------------------------------------------------------------------------------------------------------------
    // 通用辅助方法begin
    // -----------------------------------------------------------------------------------------------------------------------------------------------
    /**
     * 保存全局参数
     */
    MainWin.prototype.setSession = function(key, value) {
        if (value == null || typeof value == "undefined") {
            if (this._session.hasOwnProperty(key)) {
                delete this._session[key];
            }
        } else {
            this._session[key] = value;
        }
    };

    /**
     * 获取全局参数
     */
    MainWin.prototype.getSession = function(key) {
        return this._session[key];
    };

    /**
     * 获取远程数据
     * data
     *      请求参数
     * success
     *      回调
     * showWaiting
     *      是否显示通用等待动画
     *
     * 2016-08-23 16:34:36 添加针对无后台开发的支持
     * 使用时只需要在data中传递url.local参数，在debug模式下即可访问express中配置的路径,注意url要从'/'开始
     *
     * 2016-10-24 处理通用异常
     * 当返回值code为401时，提示登录信息已过期，请重新登录
     */
    MainWin.prototype.getData = function(data, success, showWaiting) {
        data = $.extend({
            url: ""
        }, data);
        data = $.extend(data, {
            d: $config.module,
            _local: false
        });
        var url = $config.getRequestUrl(data.url);
        return $.postWithVerify(url, data, success, function() {
            // 过期超时
            $.MessageAlert({"content": "登录信息已过期，请重新登录"});
            $win.reLogin();
        }, showWaiting);
    };

    /**
     * 获取本地数据，异步
     * className
     *      本地handler相对于{applicationId}.requesthandler包的名称，比如demo.TestHandler
     * method
     *      handler中的方法名
     * params
     *      请求参数
     * success
     *      回调
     * showWaiting
     *      是否显示通用等待动画
     */
    MainWin.prototype.getLocalData = function(className, method, params, success, showWaiting) {
        var url = $config.getLocalRequestUrl(className, method);
        params._local = true;
        return $.get(url, params, success, showWaiting);
    };

    /**
     * 获取本地数据，同步
     */
    MainWin.prototype.getLocalRequest = function(className, method, params, success, showWaiting) {
        var url = $config.getLocalRequestUrl(className, method);
        return $.getasync(url, params, success, showWaiting);
    };

    /**
     * 获取页面topbar对象
     */
    MainWin.prototype.getTopbar = function() {
        return this.topbar;
    };

    /**
     * 手势支持
     *
     * @param elem
     * @param options
     * @returns {iScroll}
     */
    MainWin.prototype.touchScroll = function(elem, options) {
        if (typeof(elem) == "object") {
            elem = elem[0];
        }
        var defaultOptions = {};
        defaultOptions.momentum = true;
        defaultOptions.handleClick = false;
        defaultOptions.useTransition = this._isTransition();
        if (/iphone/.test(navigator.userAgent.toLowerCase())) {
            defaultOptions.useTransition = true;
        }
        defaultOptions.checkDOMChanges = false;
        defaultOptions.hideScrollbar = true;
        defaultOptions.scrollbarClass = "myScrollbar";

        defaultOptions.onBeforeScrollStart = function(e) {
            if (this.absDistX > (this.absDistY + 5)) {
                e.preventDefault();
            }
            var target = e.target;
            while (target.nodeType != 1) {
                target = target.parentNode;
            }
            if (target.tagName != "SELECT" && target.tagName != "INPUT" && target.tagName != "TEXTAREA") {
                e.preventDefault();
            }
            //e.stopPropagation();
        };
        defaultOptions.onScrollMove = function(e) {
            var x = e.x;
            var y = e.y;
            if (Math.abs(x - this._startx) > 10 || Math.abs(y - this._starty) > 10) {
                $(e.target).prop("data-click", "n");
            } else {
                $(e.target).prop("data-click", "y");
            }
        };
        defaultOptions.onTouchEnd = function() {
            var self = this;
            if (self.touchEndTimeId) {
                clearTimeout(self.touchEndTimeId);
            }
            self.touchEndTimeId = setTimeout(function() {
                self.absDistX = 0;
                self.absDistY = 0;
            }, 600);
        };
        options = $.extend(defaultOptions, options);

        // 强制设置android机器的useTransition为false，以修正个别手机webview上对于topbar的兼容性问题
        // 暂时没有办法分辨手机兼容性，不使用transition会导致滚动性能降低
        if (/iphone/.test(navigator.userAgent.toLowerCase())) {
            options.useTransition = true;
        } else {
            options.useTransition = false;
        }

        return new iScroll(elem, options);
    };

    MainWin.prototype._isTransition = function() {
        var dummyStyle = document.createElement("div").style;
        var vendors = "t,webkitT,MozT,msT,OT".split(","),
            t,
            i = 0,
            l = vendors.length;
        var temp = null;
        for (; i < l; i++) {
            t = vendors[i] + "ransform";
            if (t in dummyStyle) {
                temp = vendors[i].substr(0, vendors[i].length - 1);
                break;
            }
        }
        if (temp && temp == "") {
            return false;
        } else {
            return true;
        }
    };

    /**
     * 使用iScroll5管理页面滚动，默认配置兼容移动端和浏览器
     * 使用$win.touchScroll5("#id")
     * @author Keith
     */
    MainWin.prototype.touchScroll5 = function(elem, options) {
        if (typeof(elem) == "object") {
            elem = elem[0];
        }
        // 处理滚动手势
        options = options || {};
        // 惯性
        options.momentum = true; // 允许有惯性滑动
        options.click = true;
        options.probeType = 1;
        options.bounce = true; //边界反弹
        options.shrinkScrollbars = "scale"; // 当滚动边界之外的滚动条是由少量的收缩。'clip' or 'scale'.
        options.mouseWheel = true, // 是否监听鼠标滚轮事件。
        options.scrollbars = false, // 是否显示默认滚动条
        options.fadeScrollbars = true, // 是否渐隐滚动条，关掉可以加速
        options.useTransition = this._isTransition();
        if (/iphone/.test(navigator.userAgent.toLowerCase())) {
            options.useTransition = true;
        }
        return new IScroll(elem, options);
    };

    /**
     * 调用android本地js绑定实现内容保存
     */
    MainWin.prototype.setCookie = function(key, value) {
        if (typeof Test != "undefined" && Test) {
            Test.setCookie(key, value);
        }
    };

    /**
     * 获取通过setCookie保存的内容
     */
    MainWin.prototype.getCookie = function(key) {
        var result = null;
        if (typeof Test != "undefined" && Test) {
            result = Test.getCookie(key);
        }
        return result;
    };

    //下载功能begin
    /**
     * domArray: 绑定下载的jquery dom对象
     * callback:
     *		onPaused: 暂停任务时的回调
     *		onComplete: 完成时执行的回调
     *      onProgress: 下载过程中执行的回调
     *      onError: 下载失败时执行的回调
     */
    MainWin.prototype.initDownload = function(domArray, callback) {
        var _this = this;
        domArray.each(function() {
            var item = $(this);
            var flag = item.attr("has-init-downloader");
            if (flag != "true") {
                item.attr("has-init-downloader", "true");
                _this.download(item, callback);
            }
        });
    };

    /**
     * item: 绑定下载的jquery dom对象。
     *			注意，该jquery对象必须已经被添加到dom中
     * callback:
     *      onPaused: 暂停任务时的回调
     *		onComplete: 完成时执行的回调
     *      onProgress: 下载过程中执行的回调
     *      onError: 下载失败时执行的回调
     */
    MainWin.prototype.download = function(item, callback) {
        if (!item) {
            $win.log("downloader: no dom");
            return;
        }
        var fileType = item.attr("file-type");
        var fileUrl = item.attr("file-url");
        var imageType = item.attr("image-type");
        var imageScale = item.attr("image-scale");
        if (!$.isNotBlank(imageType)) {
            imageType = "default";
        }

        if (!$.isNotBlank(fileUrl) || !$.isNotBlank(fileType)) {
            $win.log("downloader: neither file url nor file type is defined");
            return;
        }

        var params = $.extend({}, callback);
        params.item = item;
        params.url = fileUrl;
        params.fileType = fileType;
        params.imageType = imageType;

        // 下载前的处理
        if (params.fileType == "pic") {
            // 处理图片
            params.item.addClass("image-waiting");
            var heart = $("<div class=\"heart\"><div>");
            params.item.append(heart);
            if (imageScale && !JSON.parse(imageScale)) {
                params.imageWidth = 0;
            } else {
                params.imageWidth = params.item.width();
            }
        } else if (params.fileType == "audio") {
            // 先不下载，点击时在下载，下载完成自动播放
            var $audio = $("<div class=\"file-audio audio-play\"></div>");
            params.item.append($audio);
            $audio.click(function(event) {
                $(this).hide();

                // 处理音频样式
                var $progress = $("<div class=\"audio_progress\"></div>");
                params.item.append($progress);
                var width = item.width();
                var height = item.height();
                var domWidth = (width > height)
                    ? height / 2
                    : width / 2;
                domWidth = domWidth > 30
                    ? 30
                    : domWidth;
                $progress.knob({readOnly: true, width: domWidth, height: domWidth});
                params.item.$progress = $progress;

                $win._doDownload(params);

                event.preventDefault();
                event.stopPropagation();
            });
        }

        var key = $.b(params.url, 0);
        if (this._downloadQueue.hasOwnProperty(key)) {
            this._downloadQueue[key].push(params);
        } else {
            this._downloadQueue[key] = new Array();
            this._downloadQueue[key].push(params);

            if (params.fileType == "pic") {
                this._doDownload(params);
            }
        }
    };

    MainWin.prototype.startDownload = function(dom) {
        var url = dom.attr("file-url");
        var key = $.b(url, 0);
        var params = {};
        params.url = url;
        if (this._downloadQueue.hasOwnProperty(key)) {
            this._doDownload(this._downloadQueue[key][0]);
        }
    };

    // @deprecated
    MainWin.prototype.changeStatus = function(dom, status) {
        var url = dom.attr("file-url");
        var key = $.b(url, 0);
        if (this._downloadQueue[key]) {
            var task = this._downloadQueue[key];
            if (task.item) {
                var $audio = task.item.find(".file-audio");
                if ($audio) {
                    if (status == "pause") {
                        $audio.attr("playing", false);
                        $audio.removeClass("audio-stop").addClass("audio-play");
                    } else if (status == "start") {
                        $audio.attr("playing", true);
                        $audio.removeClass("audio-play").addClass("audio-stop");
                    }
                    $audio.hide().show(0);
                }
            }
        }
    };

    MainWin.prototype._doDownload = function(params) {
        var requestPath = "http://downloadfile?src=" + Base64.encode(params.url) + "&type=" + params.fileType + "&_t=" + (new Date().getTime());
        if (params.imageWidth) {
            requestPath += "&width=" + params.imageWidth;
        }
        var tempImg = $("<img src=\"" + requestPath + "\" width=\"0px\" height=\"0px\" style=\"display:none;\"/>");
        params.item.append(tempImg);
    };

    MainWin.prototype.cb_downloader = function(params) {
        if (!params.hasOwnProperty("url")) {
            $win.log("downloader callback: no url is defined");
            return;
        }
        var key = $.b(params.url, 0);
        if (this._downloadQueue.hasOwnProperty(key)) {
            var tasks = this._downloadQueue[key];
            for (var i = 0; i != tasks.length; i++) {
                var task = $.extend(tasks[i], params);
                this._downloadCb(task);
            }
        } else {
            $win.log("no task found");
        }
    };

    MainWin.prototype._downloadCb = function(task) {
        switch (task.textStatus) {
            case "complete":
                this._doComplete(task);
                this._finishDownload(task);
                break;
            case "paused":
                if (task.onPaused && typeof(task.onPaused) == "function") {
                    task.onPaused.call(this, task);
                }
                break;
            case "error":
                this._doError(task);
                this._finishDownload(task);
                break;
            case "progress":
                this._doProgress(task);
                break;
        }
    };

    MainWin.prototype._finishDownload = function(task) {
        var key = $.b(task.url, 0);
        if (this._downloadQueue.hasOwnProperty(key)) {
            delete this._downloadQueue[key];
        }
    };

    MainWin.prototype._doError = function(task) {
        var item = task.item;
        if (task.fileType == "pic") {
            // 取消动画
            item.removeClass("image-waiting");
            item.find(".heart").remove();
            item.find("img").remove();

            // 设置加载失败图片
            item.addClass("image-failed");
        } else if (task.fileType == "audio") {
            item.find("img").remove();
            if (item.$progress) {
                item.$progress.parent().remove();
            }
            var $audio = item.find(".file-audio");
            if ($audio) {
                $audio.show();
            }
        }

        if (task.onError && typeof(task.onError) == "function") {
            task.onError.call(this, task);
        }
    };

    MainWin.prototype._doProgress = function(task) {
        task.item.find("img").hide();
        var $progress = task.item.$progress;
        if ($progress) {
            var progress = parseInt(parseInt(task.current) / parseInt(task.total) * 100);
            if (progress > 0) {
                $progress.val(progress).trigger("change");
            }
        }

        if (task.onProgress && typeof(task.onProgress) == "function") {
            task.onProgress.call(this, task);
        }
    };

    MainWin.prototype._doComplete = function(task) {
        var _this = this;
        // 处理图片
        var item = task.item;
        if (task.fileType == "pic") {
            // 取消动画
            item.removeClass("image-waiting");
            item.find(".heart").remove();
            item.find("img").remove();

            // 加载本地图片
            var url = "localfile?src=" + Base64.encode(task.path);
            item.css("background-image", "url('" + url + "')");
            item.css("background-repeat", "no-repeat");
            switch (task.imageType) {
                case "fitXY":
                    item.css("background-position", "center");
                    item.css("background-size", "100% 99.9%");
                    break;
                case "fitCenter":
                    item.css("background-position", "center");
                    item.css("background-size", "contain");
                    break;
                case "center":
                    item.css("background-position", "center");
                    break;
                case "circle":
                    item.css("background-position", "center");
                    item.css("background-size", "100% 99.9%");
                    var radius = item.width();
                    item.css("border-radius", (radius / 2) + "px");
                    break;
                case "centerCrop":
                    item.css("background-position", "center");
                    item.css("background-size", "cover");
                    break;
                case "fitWidth":
                    url = "http://" + url;
                    var $img = $("<img src=\"" + url + "\" style=\"display:none;\"/>");
                    $img.get(0).onload = function() {
                        // 获取文件宽高
                        var imgWidth = $img.width();
                        var imgHeight = $img.height();
                        // 计算item自动拉伸的高度
                        var itemHeight = item.width() * imgHeight / imgWidth;
                        item.height(itemHeight);
                        // 设置背景fitXY
                        item.css("background-position", "center");
                        item.css("background-size", "100% 99.9%");
                        // 删除img
                        $img.remove();
                        if (task.onComplete && typeof(task.onComplete) == "function") {
                            task.onComplete.call(_this, task);
                        }
                    };
                    $(document.body).append($img);
                    break;
                case "default":
                    break;
            }
        } else if (task.fileType == "audio") {
            item.find("img").remove();
            if (item.$progress) {
                item.$progress.parent().remove();
            }
            var $audio = item.find(".file-audio");
            if ($audio) {
                $audio.show();
            } else {
                $audio = $("<div class=\"file-audio audio-play\"></div>");
                item.append($audio);
            }
            $win.loadAudio(task.path, function(data) {
                if (data.success) {
                    $audio.attr("audio_key", data.key);
                }
            });
            $audio.unbind("click").bind("click", function(event) {
                var audioKey = $(this).attr("audio_key");
                if ($.isNotBlank(audioKey)) {
                    var playing = $(this).attr("playing");
                    if (!$.isNotBlank(playing) || playing == "false") {
                        // 暂停其他正在播放的音频
                        $(".file-audio").each(function() {
                            var audioKey = $(this).attr("audio_key");
                            if ($.isNotBlank(audioKey)) {
                                var playing = $(this).attr("playing");
                                if (playing == "true") {
                                    $(this).attr("playing", false);
                                    $(this).removeClass("audio-stop").addClass("audio-play");
                                    $(this).hide().show(0);
                                }
                            }
                        });

                        // 从头播放音频
                        $win.playAudio(audioKey, "play");
                        $(this).attr("playing", true);
                        $(this).removeClass("audio-play").addClass("audio-stop");

                        $(this).hide().show(0);
                    } else if (playing == "true") {
                        // 暂停音频
                        $win.playAudio(audioKey, "pause");
                        $(this).attr("playing", false);
                        $(this).removeClass("audio-stop").addClass("audio-play");

                        $(this).hide().show(0);
                    }
                }
                event.preventDefault();
                event.stopPropagation();
            });

            setTimeout(function() {
                $audio.trigger("click");
            }, 500);
        }

        // 处理回调
        if (task.onComplete && typeof(task.onComplete) == "function") {
            task.onComplete.call(this, task);
        }
    };
    //下载功能end

    // js-binding全局辅助功能函数

    /**
     * 注册本地调用的脚本回调方法
     */
    MainWin.prototype.jsRegister = function(key, callback) {
        if (this._jsCbMap.hasOwnProperty(key)) {
            delete this._jsCbMap[key];
        }
        if (typeof callback != "undefined" && callback != null) {
            this._jsCbMap[key] = callback;
        }
    };

    /**
     * 调用jsRegister注册的回调，调用后删除该注册
     * key
     *      注册方法名
     * params
     *      调用参数
     */
    MainWin.prototype.jsCallback = function(key, params) {
        if (this._jsCbMap.hasOwnProperty(key)) {
            var cb = this._jsCbMap[key];
            cb.call(this, params);
            // backward/cancel是系统事件，不需要重置
            if (key != "backward" && key != "cancel") {
                this.jsRegister(key);
            }
        } else {
            this.log("事件" + key + "未注册。");
        }
    };

    /**
     * 扫描二维码
     * 回调参数格式
     *      {\"success\": true, \"code\": xxxx}
     */
    MainWin.prototype.scanQrcode = function(callback) {
        this.jsRegister("scanqrcode", callback);
        window.location.href = this.scheme + "://scanqrcode";
    };

    /**
     * 调用拍照功能
     * 回调参数格式，filepath为拍照成功之后的本地图片路径
     *      {\"success\": true, \"filepath\": xxxxx}
     *      {\"success\": false, \"filepath\": \"\"} 取消拍照或者拍照失败
     */
    MainWin.prototype.takePhoto = function(callback) {
        this.jsRegister("takephoto", callback);
        window.location.href = this.scheme + "://takephoto";
    };

    /**
     * 调用选照片功能
     * 回调参数格式，JSONArray表示选取的图片，length可能为0则表示未选择
     *      [{\"filepath\": \"xxxxxx\"},{\"filepath\": \"xxxxxx\"}]
     */
    MainWin.prototype.takeAlbum = function(callback) {
        this.jsRegister("takealbum", callback);
        window.location.href = this.scheme + "://takealbum";
    };

    /**
     * 加载音频文件
     * @return 加载成功之后的key
     */
    MainWin.prototype.loadAudio = function(path, callback) {
        this.jsRegister("loadaudio", callback);
        var param = {
            key: $.b(path, 0),
            src: path
        };
        window.location.href = this.scheme + "://loadaudio?" + Base64.encode(JSON.stringify(param));
        return param.key;
    };

    /**
     * 调整音频状态
     * key
     *      loadAudio返回的key
     * status
     *      play    播放音频
     *      pause   暂停音频
     */
    MainWin.prototype.playAudio = function(key, status) {
        var param = {
            key: key,
            status: status
        };
        window.location.href = this.scheme + "://playaudio?" + Base64.encode(JSON.stringify(param));
    };

    /**
     * 关闭媒体音量
     */
    MainWin.prototype.closeAudio = function() {
        window.location.href = this.scheme + "://closeaudio";
    };

    /**
     * 打开媒体音量
     */
    MainWin.prototype.openAudio = function() {
        window.location.href = this.scheme + "://openaudio";
    };

    /**
     * 拨打电话
     */
    MainWin.prototype.takeCall = function(phoneNum) {
        window.location.href = this.scheme + "://takecall?" + Base64.encode("{\"phone\":\"" + phoneNum + "\"}");
    };

    /**
     * 调用js绑定输出日志
     */
    MainWin.prototype.log = function(text) {
        if (typeof Test == "undefined" || null == Test || typeof Test.log != "function") {
            console.log(text);
            return;
        }
        Test.log(text);
    };

    /**
     * 获取临时文件目录大小
     */
    MainWin.prototype.getTempFolderSize = function(callback) {
        if (callback && typeof callback == "function") {
            this.jsRegister("getlocaltempfoldersize", callback);
        }

        window.location.href = this.scheme + "://getlocaltempfoldersize";
    };

    /**
     * 清空缓存目录
     */
    MainWin.prototype.clearCache = function(callback) {
        if (callback && typeof callback == "function") {
            this.jsRegister("clearcache", callback);
        }

        window.location.href = this.scheme + "://clearcache";
    };

    /**
     * 释放音频文件，用于跳转页面时停止正在播放的音频文件
     */
    MainWin.prototype.releaseAll = function() {
        window.location.href = this.scheme + "://releaseall";
    };

    /**
     * 调用支付宝移动支付功能
     * params:
     *      traderNo: 订单号，多个订单号使用"_"隔开,最长64位
     *      subject: 商品名称，最长128位
     *      totalFee: 总额
     *      body: 商品详情，最长512位
     *
     *      额外参数，预留，暂不支持
     *      app_id: string类型，平台相关ios/android
     *      appenv: string类型，标识客户端来源，可以不填
     */
    MainWin.prototype.payOrder = function(params, callback) {
        if (!params || !params.traderNo || !params.subject || !params.totalFee || !params.body) {
            $win.log("请求参数不全");
            return;
        }
        this.jsRegister("payorder", callback);

        window.location.href = this.scheme + "://payorder?" + Base64.encode(JSON.stringify(params));
    };

    /**
     * 根据本地文件路径，返回可以被页面展示的文件链接
     * 常用于拍照或选取图片之后页面展示图片预览
     */
    MainWin.prototype.getLocalFileUri = function(path) {
        path = path.replace("\\/", "/");
        return "localfile?src=" + Base64.encode(path) + "&_t=" + (new Date().getTime());
    };

    /**
     * 获取当前版本号
     * 返回
     *      version_name    文件版本号
     *      version_code    数字版本号
     */
    MainWin.prototype.getVersionInfo = function() {
        // 注意 该方法需要iOS单独实现
        if (typeof Test != "undefined" && Test) {
            return Test.getVersionInfo();
        }

        return {};
    };

    /**
     * 批量图片预览
     * params是一个JSONObject
     *     {
     *         index: 0,
     *         images: [
     *             {url: "xxx/xxx/xx/xx.jpg",mode:1},
     *             {url: "xxx/xxx/xx/xx.jpg",mode:0},
     *             {url: "xxx/xxx/xx/xx.jpg",mode:0}
     *         ]
     *     }
     *  index表示显示第几张，默认0，即第一张，如果数字大于图片总长数，显示最后一张
     *  mode，0代表本地图片，1代表网络图片，默认网络图片1
     *
     */
    MainWin.prototype.showImages = function(params) {
        // 注意 该方法需要iOS单独实现
        window.location.href = this.scheme + "://showimages?" + Base64.encode(JSON.stringify(params));
    };

    MainWin.prototype._initSystem = function() {
        if (typeof Test != "undefined" && Test) {
            this.getCustomScheme();

            var config = JSON.parse(Test.initSystemConfig());
            if (config && config.hasOwnProperty("autoplay")) {
                this.autoplay = config.autoplay;
            }
        }
    };

    MainWin.prototype.getCustomScheme = function() {
        if (typeof Test != "undefined" && Test) {
            this.scheme = Test.getCustomScheme();
        }
    };

    // -----------------------------------------------------------------------------------------------------------------------------------------------
    // 应用定制模块
    // -----------------------------------------------------------------------------------------------------------------------------------------------
    MainWin.prototype._getUserInfo = function() {
        if (typeof Test != "undefined" && Test) {
            this.userInfo = JSON.parse(Test.getUserInfo());
        }
    };

    MainWin.prototype.setUserInfo = function(info) {
        this.userInfo = info;
        if (typeof Test != "undefined" && Test) {
            Test.updateUserInfo(JSON.stringify(info));
        }
    };

    MainWin.prototype.isLogin = function() {
        return this.userInfo.id != 0 && this.userInfo.id != undefined && this.userInfo.id != null;
    };

    return MainWin;
});
